joEl.register('form-config-ele-option', {
    props: {
        icon: {
            type: [String, Array],
            default: 'fa-bars'
        },
        name: {
            type: String,
            default: ''
        },
        type: {
            type: String,
            default: '',
            required: true
        },
        subType: {
            type: String,
            default: '',
        },
    },
    data: function () {
        return {
            ele: {
                name: this.name,
                type: this.type,
                subType: this.subType,
            }
        };
    },
    // @dragover.stop.prevent="dragOverEle($event, ele)"
    // @drop.stop="dropEle($event, ele)"
    template: `
        <div class="form-config-ele-option"
            draggable="true"
            @dragstart.stop.self="dragStartEle($event, ele)"
            @dragend.stop.self="dragEndEle($event, ele)"
        >
            <div class="form-config-icon">
                <i class="fa" :class="icon"></i>
            </div>
            <div class="form-config-ele-name">{{name}}</div>
        </div>
    `,
    methods: {
        dragStartEle(event, ele) {
            this.$root.dragStartEleOption(event, ele);
        },
        dragEndEle(event, ele) {
            this.$root.dragEndEleOption(event, ele);
        },
        // dragOverEle(event, ele) {
        //     this.$root.dragOverEleOption(event, ele);
        // },
        // dropEle(event, ele) {
        //     this.$root.dropEleOption(event, ele);
        // },
    },
    mounted() {

    }
});
joEl.register('form-config-ele-wrap', {
    props: {
        ele: {
            type: Object,
            default: {}
        },
    },
    data: function () {
        return {};
    },
    computed: {
        wrapActiveEleId() {
            return this.$root.formConfigActiveEleId;
        }
    },
    template: `
        <div class="form-config-ele-wrap"
            :class="{ 'form-config-ele-wrap-active' : ele.id == wrapActiveEleId }"
            @click="eleWrapChecked(ele)"
            draggable="true"
            @dragstart.stop.self="dragStartEle($event, ele)"
            @dragend.stop.self="dragEndEle($event, ele)"
            @dragover.stop.prevent="dragOverEle($event, ele)"
            @drop.stop="dropEle($event, ele)"
        >
            ---{{ele}}.
        </div>
    `,
    methods: {
        // 页面配置中组件选中
        eleWrapChecked(ele) {
            this.$root.formConfigActiveEle = ele;
        },
        dragStartEle(event, ele) {
            this.$root.dragStartEleWrap(event, ele);
        },
        dragEndEle(event, ele) {
            this.$root.dragEndEleWrap(event, ele);
        },
        dragOverEle(event, ele) {
            this.$root.dragOverEleWrap(event, ele);
        },
        dropEle(event, ele) {
            this.$root.dropEleWrap(event, ele);
        },
    },
    mounted() {

    }
});
// 低代码表单配置
var VUE_LOW_CODE_FORM_CONFIG_V2 = {
    data() {
        return {
            // 表单配置当前选中面板, fields/component/highComponent/chart
            formConfigCollapse: 'form',
            // 表单配置拖拽类型
            formConfigDragType: {
                option: {code: 'option', text: '被拖拽的是左侧组件选项'},
                inner: {code: 'inner', text: '被拖拽的是表单配置容器中已有的元素'},
            },
            // 当前正在拖拽的组件
            dragContext: {
                // 拖拽类型, formConfigDragType
                dragType: '',
                dragEleOption: null,
            },
            // 表单(页面)配置对象
            formPageConfig: {
                // 元素(组件)集合
                elementList: []
            },
            // 当前选中的组件
            formConfigActiveEle: null,
        };
    },
    computed: {
        // 当前选中组件的id
        formConfigActiveEleId() {
            return this.formConfigActiveEle ? this.formConfigActiveEle.id : '';
        },
    },
    methods: {
        // 拖放到表单配置容器
        dropFormConfigContainer(event) {
            console.info('在表单容器拖放', event, this.dragContext);
            if (this.dragContext.dragType === this.formConfigDragType.option.code) {
                if (this.dragContext.dragEleOption) {
                    this.formPageConfig.elementList.push({
                        id: jo.getUUID(16),
                        type: this.dragContext.dragEleOption.type,
                        subType: this.dragContext.dragEleOption.subType,
                    });
                }
            } else {
                console.info('表单容器不支持此拖拽类型', this.dragContext);
            }
        },
        dragStartEleOption(event, ele) {
            console.info('开始拖拽Option', ele)
            this.dragContext = {
                dragType: this.formConfigDragType.option.code,
                dragEleOption: ele,
            };
        },
        dragEndEleOption(event, ele) {
            console.info('结束拖拽Option', ele)
            this.dragContext = {};
            $('.form-config-ele-wrap').removeClass('form-config-ele-wrap-drop-center');
            $('.form-config-ele-wrap').removeClass('form-config-ele-wrap-drop-before');
            $('.form-config-ele-wrap').removeClass('form-config-ele-wrap-drop-after');
        },
        // 组件包装器拖拽开始
        dragStartEleWrap(event, ele) {
            console.info('开始拖拽Wrap', ele)
            this.dragContext = {
                dragType: this.formConfigDragType.inner.code,
                dragEleOption: ele,
            };
        },
        // 组件包装器拖拽结束
        dragEndEleWrap(event, ele) {
            console.info('结束拖拽Wrap', ele)
            this.dragContext = {};
            $('.form-config-ele-wrap').removeClass('form-config-ele-wrap-drop-center');
            $('.form-config-ele-wrap').removeClass('form-config-ele-wrap-drop-before');
            $('.form-config-ele-wrap').removeClass('form-config-ele-wrap-drop-after');
        },
        // 组件包装器在目标对象上拖动, ele: 目标对象
        dragOverEleWrap(event, ele) {
            if (!ele || !this.dragContext.dragEleOption) {
                console.info('[dragOverEleWrap] 拖拖拽和拖放的存在无效对象,pass');
                return;
            }
            if (this.eleIncludeAnotherEle(ele, this.dragContext.dragEleOption)) {
                console.info('[dragOverEleWrap] 拖拖拽和拖放的是同一个对象或者包含拖放对象,pass', this.dragContext.dragEleOption, ele);
                return;
            }
            // 鼠标在目标对象的位置
            var position = jo.getPositionDetail(event, 'form-config-ele-wrap');
            // 清空样式
            $('.form-config-ele-wrap').removeClass('form-config-ele-wrap-drop-center');
            $('.form-config-ele-wrap').removeClass('form-config-ele-wrap-drop-before');
            $('.form-config-ele-wrap').removeClass('form-config-ele-wrap-drop-after');
            if (position.atCenterOf9) {
                // 放到目标对象的子节点
                $(event.target).addClass('form-config-ele-wrap-drop-center');
            } else if (position.atLeftOf9 || position.atUpOf9) {
                // 左/上则放到目标前面
                $(event.target).addClass('form-config-ele-wrap-drop-before');
            } else {
                // 右/下放到目标后面
                // 定位失败默认放到目标后面
                $(event.target).addClass('form-config-ele-wrap-drop-after');
            }
        },
        // 组件包装器拖放
        dropEleWrap(event, ele) {
            console.info('在表单容器拖放', event, this.dragContext);
            if (!ele || !this.dragContext.dragEleOption) {
                console.info('拖拖拽和拖放的存在无效对象,pass');
                return;
            }
            if (this.eleIncludeAnotherEle(ele, this.dragContext.dragEleOption)) {
                console.info('拖拖拽和拖放的是同一个对象或者包含拖放对象,pass', this.dragContext.dragEleOption, ele);
                return;
            }
            var _this = this;
            var dragEle;
            if (this.dragContext.dragType === this.formConfigDragType.option.code) {
                if (this.dragContext.dragEleOption) {
                    dragEle = {
                        id: jo.getUUID(16),
                        type: this.dragContext.dragEleOption.type,
                        subType: this.dragContext.dragEleOption.subType,
                    };
                }
            } else if (this.dragContext.dragType === this.formConfigDragType.inner.code) {
                if (this.dragContext.dragEleOption && ele) {
                    if (!ele.childrenList) {
                        ele.childrenList = [];
                    }
                    // 从原来位置删除
                    this.removeEleWrap(this.dragContext.dragEleOption);
                    dragEle = this.dragContext.dragEleOption;
                }
            } else {
                console.info('元素wrap不支持此拖拽类型', this.dragContext);
            }

            if (dragEle) {
                // 放到目标对象的对应位置
                var position = jo.getPositionDetail(event, 'form-config-ele-wrap');
                if (position.atCenterOf9) {
                    // 放到目标对象的子节点
                    if (!ele.childrenList) {
                        ele.childrenList = [];
                    }
                    ele.childrenList.push(dragEle);
                } else {
                    // 拖放目标在哪个集合里
                    var list = this.findEleOriginList(ele, this.formPageConfig.elementList) || this.formPageConfig.elementList;
                    // 拖放目标在集合的位置
                    var idx = this.findEleIdx(ele, list);
                    if (idx < 0) {
                        // 目标位置匹配失败则默认放到最后, 正常情况到不了这里
                        list.push(dragEle);
                        console.warn('[组件包装器拖放] 目标位置匹配失败,拖拽对象和目标对象打印:', this.dragContext, ele);
                    } else {
                        if (position.atLeftOf9 || position.atUpOf9) {
                            // 左/上则放到目标前面
                            list.splice(idx, 0, dragEle);
                        } else {
                            // 右/下放到目标后面
                            // 定位失败默认放到目标后面
                            list.splice(idx + 1, 0, dragEle);
                        }
                    }
                }

            }
        },
        // 拖拽在目标对象上移动, 啥也不干, 没有这个事件则拖放事件不生效
        dragOverNothing(event) {
        },
        // dragOverEleOption(event, ele) {
        //     console.info('拖拽移动', ele)
        // },
        // dropEleOption(event, ele) {
        //     console.info('拖放', ele)
        // },


        // 判断元素是否在另一个元素中, 也就是是否相同或者是子节点
        eleIncludeAnotherEle(ele, another) {
            if (ele.id == another.id) {
                return true;
            }
            if (another.childrenList) {
                for (let i = 0; i < another.childrenList.length; i++) {
                    var item = another.childrenList[i];
                    if (this.eleIncludeAnotherEle(ele, item)) {
                        return true;
                    }
                }
            }
            return false;
        },
        // 查找元素在哪个集合中
        findEleOriginList(eleWrap, list) {
            if (list && list.length > 0) {
                // 判断在不在list
                for (let i = 0; i < list.length; i++) {
                    var item = list[i];
                    if (item.id == eleWrap.id) {
                        return list;
                    }
                }
                // 判断在不在孩子节点
                for (let i = 0; i < list.length; i++) {
                    var item = list[i];
                    if (item.childrenList) {
                        var list2 = this.findEleOriginList(eleWrap, item.childrenList);
                        if (list2) {
                            return list2;
                        }
                    }
                }
            }
            return null;
        },
        // 从表单配置的元素列表中删除指定元素
        removeEleWrap(eleWrap) {
            this.removeEleWrapFromList(eleWrap, this.formPageConfig.elementList);
        },
        // 删除元素从一个列表中
        removeEleWrapFromList(eleWrap, eleList) {
            if (eleList) {
                var _this = this;
                var delIdx = this.findEleIdx(eleWrap, eleList);
                if (delIdx >= 0) {
                    eleList.splice(delIdx, 1);
                    console.info('[删除元素老位置] 位置:', delIdx);
                } else {
                    // 再从子节点中删除
                    jo.forEach(eleList, function (item, i) {
                        if (item.childrenList) {
                            _this.removeEleWrapFromList(eleWrap, item.childrenList);
                        }
                    });
                }
            }
        },
        // 获取元素在集合的位置
        findEleIdx(eleWrap, eleList) {
            var idx = -1;
            if (eleList) {
                jo.forEach(eleList, function (item, i) {
                    if (item.id == eleWrap.id) {
                        if (idx >= 0) {
                            console.error('[获取元素在集合的位置] 重复匹配到元素,上次匹配索引+本次索引+集合输出:', idx, i, eleList);
                        }
                        idx = i;
                    }
                });
            }
            return idx;
        },

    }
};